home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Light ROM 1
/
LIGHT-ROM 1 (Amiga Library Services)(1994).iso
/
ffdisks
/
d941.lha
/
YAMFG
/
Source
/
YAMFG.English
next >
Wrap
Text File
|
1993-12-20
|
27KB
|
869 lines
; YAMFG 1.0 - ©1993 F.Delacroix- FreeWare
; written on HiSoft Devpac 3
; all system includes were included at assembly time using the
; system.gs file of Devpac 3. If you use another assembly,just
; include them individually
include exec/execbase.i ; some more includes: ExecBase struct
include hardware/custom.i ; custom hardware: for random numbers
include libraries/reqtools.i ; includes for reqtools.library
include libraries/reqtools_lib.i
DEFAULT_WIDTH EQU 20 ; useful constants: self-explanatory...
DEFAULT_HEIGHT EQU 20
DEFAULT_MINES EQU 40
MAX_WIDTH EQU 24
MAX_HEIGHT EQU 21
UP EQU $4c ; keys used to move the tank
DOWN EQU $4d
RIGHT EQU $4e
LEFT EQU $4f
STATUSX EQU 4 ; coordinates for the status-line
STATUSY EQU 18
move.l 4.w,a6
move.l ThisTask(a6),a4 ;find my task (same as FindTask(0))
moveq #0,d0
tst.l pr_CLI(a4) ; were we called from CLI ?
bne.s FromCLI ; yes,we were...
lea pr_MsgPort(a4),a0 ; no: get the WBStartup message
jsr _LVOWaitPort(a6) ; sent by the Workbench
lea pr_MsgPort(a4),a0
jsr _LVOGetMsg(a6)
FromCLI move.l d0,WBStarter ; and store it (0 if from CLI)
lea ReqTools.Name(pc),a1 ; let's open the reqtools.library
moveq #0,d0
jsr _LVOOpenLibrary(a6)
move.l d0,ReqTools.Base
beq OutOfHere ; no reqtools.library: exit program
move.l ReqTools.Base(pc),a0 ; and get other library bases from it
move.l rt_IntuitionBase(a0),Intuition.Base
move.l rt_GfxBase(a0),Graphics.Base
lea YAMFG.NewWindow(pc),a0 ; let's open the window
move.l Intuition.Base(pc),a6
jsr _LVOOpenWindow(a6)
move.l d0,YAMFG.Window
beq CloseReqTools ; cannot open window !
move.l YAMFG.Window(pc),a0 ; let's attach the menues to the window
lea Project.Menu(pc),a1
jsr _LVOSetMenuStrip(a6)
tst.l d0
beq CloseWindow ; failed ! (shouldn't occur)
move.l YAMFG.Window(pc),a0 ; store important data from our window
move.l wd_RPort(a0),YAMFG.RastPort ; RastPort for graphics
move.l wd_UserPort(a0),YAMFG.UserPort ; UserPort for messages
bra NewGame ; let's begin a new game...
WaitMessage
move.l YAMFG.UserPort(pc),a0 ; let's wait for a message from
move.l 4.w,a6 ; Intuition to our window...
jsr _LVOWaitPort(a6)
NextMessage
move.l YAMFG.UserPort(pc),a0 ; And get it!
move.l 4.w,a6
jsr _LVOGetMsg(a6)
tst.l d0
beq.s WaitMessage ; Was there actually one ?
move.l d0,a1 ; Yeah !
move.l im_Class(a1),d7 ; Store important fields:Class
move.w im_Code(a1),d6 ; and Code
jsr _LVOReplyMsg(a6) ; then reply to Intuition
cmp.l #IDCMP_CLOSEWINDOW,d7 ; Should we quit ?
beq ClearMenus ; Yes? Then go...
cmp.w #IDCMP_RAWKEY,d7 ; Was a key pressed
bne NoRawKey
btst #IECODEB_UP_PREFIX,d6 ; ignore if a key was released
bne NextMessage
tst.b FinishFlag ; was the game finished ?
bne NewGame ; yes? then begin a new one
move.w MinerX(pc),d0 ; no: get the position of the tank
move.w MinerY(pc),d1
cmp.w #UP,d6 ; Up ?
beq.s GoUp
cmp.w #DOWN,d6 ; Down ?
beq.s GoDown
cmp.w #RIGHT,d6 ; Right ?
beq.s GoRight
cmp.w #LEFT,d6 ; Or left ?
bne NextMessage ; None of that ?? then get next Message
subq.w #1,d0 ; 1 step left
bra.s DirectionGot
GoRight addq.w #1,d0 ; 1 step right
bra.s DirectionGot
GoDown addq.w #1,d1 ; 1 step down
bra.s DirectionGot
GoUp subq.w #1,d1 ; 1 step up
DirectionGot
bsr CheckBounds ; check if tank does not go out of bounds
bsr MoveMiner ; then move it
move.l Width(pc),d0 ; Is tank on the right edge ?
subq.l #1,d0
cmp.w MinerX(pc),d0
bne.s NoGoal
move.l Height(pc),d0 ; Is it on the bottom ?
subq.l #1,d0
cmp.w MinerY(pc),d0
bne.s NoGoal ; yes ! The goal is reached ! (Congrats!)
lea Won.MSG(pc),a0 ; Get winning message..
bra.s EndOfGame ; and end the game
NoGoal moveq #0,d0 ; Target not reached yet...
move.w MinerY(pc),d0 ; Turn tank position into an offset for
mulu Width+2(pc),d0 ; the mine array: offset=Width*Y+X
add.w MinerX(pc),d0
lea Mines.Array(pc),a2
tst.b (a2,d0) ; test if tank is on a mine
beq.s ShowNumber ; No!!
lea Lost.MSG(pc),a0 ; Uh-Oh: a mine !
EndOfGame
st FinishFlag ; The game is finished
bsr DisplayStatus ; Display the end message (won or lost)
bsr RevealMines ; and display mine positions
bra NextMessage ; go back to loop
NewGame
clr.b FinishFlag ; When a game begins,it is not finished yet
move.l YAMFG.RastPort(pc),a1
moveq #RP_JAM2,d0
move.l Graphics.Base(pc),a6
jsr _LVOSetDrMd(a6) ; set drawmode to RP_JAM2 (uses both pens)
move.l YAMFG.RastPort(pc),a1
moveq #0,d0
jsr _LVOSetAPen(a6) ; select color 0
move.l YAMFG.RastPort(pc),a1
move.l #4,d0 ; draw a big rectangle to clear all the display
move.l #12,d1
move.l #396,d2
move.l #196,d3
jsr _LVORectFill(a6)
bsr DrawMinesBorder ; draw a border around play area
bsr PlaceMines ; Generate random mine positions
clr.w MinerX ; Place the tank in the upper left corner
clr.w MinerY
bsr ShowMiner ; draw the tank
ShowNumber
lea Mines.Array(pc),a2
moveq #0,d0
move.w MinerY(pc),d0 ; turn tank position into offset for table
mulu Width+2(pc),d0
add.w MinerX(pc),d0
add.l d0,a2 ; tank emplacement within mine array
moveq #0,d1
move.l Width(pc),d3 ; d3=Width of play area
move.l Height(pc),d4
move.l d3,d5 ; d5=Width-1
subq.l #1,d5
subq.l #1,d4 ; d4=Height-1
move.l d3,d6
neg.l d6 ; d6=-Width
tst.w MinerY ; is tank on upper edge ?
beq.s No9 ; yes? then don't test above tank!
tst.b (a2,d6.l) ; mine in position 8 ?
beq.s No8 ; note: I follow these conventions within
addq.l #1,d1 ; the source: 789
No8 tst.w MinerX ; 4 6
beq.s No7 ; 123
tst.b -1(a2,d6.l) ; if the array in tested position
beq.s No7 ; (in order of appearance:8,7,9,4,6,1,2,3)
addq.l #1,d1 ; is not zero, then there is a mine,and
No7 cmp.w MinerX(pc),d5 ; the mine counter (d1) is incremented
beq.s No9 ; Of course,if the position does not make
tst.b 1(a2,d6.l) ; a sense (if the tank is on an edge of
beq.s No9 ; the play area),the position is not tested.
addq.l #1,d1
No9 tst.w MinerX
beq.s No4
tst.b -1(a2)
beq.s No4
addq.l #1,d1
No4 cmp.w MinerX(pc),d5
beq.s No6
tst.b 1(a2)
beq.s No6
addq.l #1,d1
No6 cmp.w MinerY(pc),d4
beq.s No3
tst.w MinerX
beq.s No1
tst.b -1(a2,d3)
beq.s No1
addq.l #1,d1
No1 tst.b (a2,d3)
beq.s No2
addq.l #1,d1
No2 cmp.w MinerX(pc),d5
beq.s No3
tst.b 1(a2,d3)
beq.s No3
addq.l #1,d1
No3
add.b #'0',d1 ; turn mine counter into a displayable digit
move.b d1,Mines.Number ; and store it for printing
lea MinesNumber.MSG(pc),a0 ; This is the 'Mines around' message
bsr DisplayStatus ; display it!
bra NextMessage ; next user action...
NoRawKey
cmp.l #IDCMP_MENUPICK,d7 ; was a menu selected ?
bne NextMessage ; no: ignore that a strange message!
DoNextSelect
move.w d6,d0 ; this is the menu number given by Intuition
lea Project.Menu(pc),a0 ; our menu strip
move.l Intuition.Base(pc),a6
jsr _LVOItemAddress(a6) ; get address of selected MenuItem
move.l d0,a5
tst.l d0 ; was there one actually ?
beq NextMessage ; No: end of menu treatment
move.w mi_NextSelect(a5),d6 ; store menunumber of next selected
move.l mi_SIZEOF(a5),a1 ; This is a custom field in the item
cmp.l #0,a1 ; structure: it points to the routine to execute..
beq DoNextSelect ; if there is one of course
jsr (a1) ; execute it !
bra.s DoNextSelect ; then process next menu selection
ClearMenus ; Time to quit the game !!
move.l YAMFG.Window(pc),a0 ; remove menues from our window
move.l Intuition.Base(pc),a6
jsr _LVOClearMenuStrip(a6)
CloseWindow
move.l YAMFG.Window(pc),a0 ; close the window
move.l Intuition.Base(pc),a6
jsr _LVOCloseWindow(a6)
CloseReqTools
move.l ReqTools.Base(pc),a1 ; close the reqtools.library
move.l 4.w,a6
jsr _LVOCloseLibrary(a6)
OutOfHere
move.l WBStarter(pc),d1 ; were we called from Workbench ?
beq.s BackToCLI ; no: there is no more to be done
jsr _LVOForbid(a6) ; yes: we must reply to the WBStartup
move.l d1,a1 ; message we received on start of the prog
move.l 4.w,a6 ; note that the Forbid() call is absolutely
jsr _LVOReplyMsg(a6) ; necessary.
BackToCLI
moveq #0,d0 ; so that CLI does not display strangest codes...
rts ; This is the sad end ...
; subroutine that initializes some display variables and draws the
; rectangular border and displays the target picture
DrawMinesBorder
movem.l d0-d1/a0-a1/a6,-(sp)
move.l Width(pc),d0 ; Width in pixels=Width*16
lsl.l #4,d0
move.l Height(pc),d1 ; Height in pixels=Height*8
lsl.l #3,d1
addq.l #1,d0
addq.l #1,d1
move.w d0,Border.Right1 ; store these values for drawing the
move.w d0,Border.Right2 ; border
move.w d0,Border.Right3
move.w d1,Border.Bot1
move.w d1,Border.Bot2
move.w d1,Border.Bot3
move.l YAMFG.RastPort(pc),a0 ; the window RastPort
lea YAMFG.Border(pc),a1 ; the Border structure
move.l Width(pc),d0 ; Compute the PlayX variable to center
lsl.l #3,d0 ; the playing field: PlayX=(400-Width*16)/2
neg.l d0 ; PlayX=200-Width*8
add.l #200,d0
move.l d0,PlayX
move.l Height(pc),d1 ; Compute the PlayY variable in a similar
lsl.l #2,d1 ; way: PlayY=(200-Height*8)/2=100-Height*4
neg.l d1
add.l #100,d1
addq.l #3,d1 ; and add 3 pixels
cmp.l #STATUSY+4,d1 ; but do not overlap the Status Line
bge.s NotTooLow ; area !!
move.l #STATUSY+4,d1 ; If it's the case,then lower it a bit
NotTooLow
move.l d1,PlayY
move.l Intuition.Base(pc),a6
jsr _LVODrawBorder(a6) ; Draw the damn border
move.l YAMFG.RastPort(pc),a0 ; Necessary for all graphic operations
lea Target.Image,a1 ; The image structure for the target
move.l Width(pc),d0 ; X Y positions of the target:
subq.l #1,d0 ; in the lower right corner
lsl.l #4,d0
add.l PlayX(pc),d0
move.l Height(pc),d1
subq.l #1,d1
lsl.l #3,d1
add.l PlayY(pc),d1
jsr _LVODrawImage(a6) ; let Intuition draw it.
movem.l (sp)+,d0-d1/a0-a1/a6
rts
; this is the subroutine that randomly places the mines in the array
; It is NOT guaranteed that there is a way out if the mines are too
; numerous. The routine uses a classic FastRand() algorythm which takes
; the position of the raster as seed
PlaceMines
movem.l d0/d3-d5/a2,-(sp)
lea Mines.Array(pc),a2 ; array to fill
move.l Width(pc),d0
mulu Height+2(pc),d0 ; Size of the array
move.l d0,d3
subq.l #1,d0 ; a dbra loop counts down to -1
ClearMines
clr.b (a2)+ ; wipe all mines from the array
dbra d0,ClearMines
moveq #0,d5
move.w $DFF000+vhposr,d5 ; get the seed from the vhposr registr
lea Mines.Array(pc),a2 ; restore a2
move.l Mines(pc),d4 ; number of mines to place
cmp.l d4,d3 ; is it possible ??
bgt.s AnotherRandom ; yes it is
move.l d3,d4 ; there are far too many mines !! Reduce the number
subq.l #4,d4 ; this is only for safety: who would want a game where
AnotherRandom ; every move is loss ?
add.l d5,d5 ; This is the FastRand() routine that generates
bhi.s .NoEOR ; a seemingly random series of numbers
eor.l #$1D872B41,d5 ; Why this number ? This is a good question.
.NoEOR
moveq #0,d0 ; divide the random number by the array size so that
move.w d5,d0 ; the modulo reflects a valid position in the grid
divu d3,d0
swap d0
tst.w d0 ; I don't want a mine in the upper left corner!
beq AnotherRandom
tst.b (a2,d0.w) ; Is there already a mine there ?
bne.s AnotherRandom ; Yes?? Well use another offset
move.b #1,(a2,d0.w) ; No: well now there is one
subq #1,d4 ; Was it the last mine to be placed ?
bne AnotherRandom ; No.
movem.l (sp)+,d0/d3-d5/a2 ; Yes: restore registers and
rts ; return
; This displays the tank..
ShowMiner
movem.l d0-d1/a0-a1/a6,-(sp)
move.l YAMFG.RastPort(pc),a0
lea Tank.Image,a1 ; Image structure for the tank
moveq #0,d0
move.l d0,d1
move.w MinerX(pc),d0
move.w MinerY(pc),d1
lsl.l #4,d0
lsl.l #3,d1
add.l PlayX(pc),d0 ; X=PlayX+MinerX*16
add.l PlayY(pc),d1 ; Y=PlayY+MinerY*8
move.l Intuition.Base(pc),a6
jsr _LVODrawImage(a6) ; Draw it. Easy no?
movem.l (sp)+,d0-d1/a0-a1/a6
rts
; This checks whether the tank has gone out of bounds,in which case it is
; placed back on the edge of the grid. This routine is called with the
; newly demanded position in D0 and D1 (X and Y respectively).
CheckBounds
ext.l d0 ; Turn X position into a longword
cmp.l Width(pc),d0 ; Too far on the right ?
blt.s NotRightEdge
move.l Width(pc),d0
subq.l #1,d0
NotRightEdge
tst.l d0 ; Too far on the left ?
bge.s NotLeftEdge
moveq #0,d0
NotLeftEdge
ext.l d1 ; Turn Y position into a longword
tst.l d1 ; Too far up ?
bge.s NotUpEdge
moveq #0,d1
NotUpEdge
cmp.l Height(pc),d1 ; Too far down ?
blt.s NoDownEdge
move.l Height(pc),d1
subq.l #1,d1
NoDownEdge
rts
; This routine erases the tank image and then draw it at the position
; given by D0 and D1 (X and Y).It also updates the MinerX and MinerY vars.
MoveMiner
bsr.s EraseMiner
move.w d0,MinerX
move.w d1,MinerY
bra ShowMiner
; This erases the tank image by printing two spaces in color 3
EraseMiner
movem.l d0-d1/a0-a1/a6,-(sp)
move.l YAMFG.RastPort(pc),a1
moveq #0,d0 ; X=PlayX+MinerX*16
move.l d0,d1 ; Y=PlayY+MinerY*8
move.w MinerX(pc),d0
move.w MinerY(pc),d1
lsl.l #4,d0
lsl.l #3,d1
add.l PlayX(pc),d0
add.l PlayY(pc),d1
addq.l #6,d1 ; Add 6 to the Y position to get the baseline of the
move.l Graphics.Base(pc),a6 ; standard topaz font.
jsr _LVOMove(a6) ; Move the graphic cursor there
move.l YAMFG.RastPort(pc),a1
moveq #3,d0 ; set the B pen to color 3 (orange or blue on
jsr _LVOSetBPen(a6) ; normal-coloured workbenchs)
move.l YAMFG.RastPort(pc),a1
moveq #RP_JAM2,d0 ; set the drawmode to RP_JAM2 so that
jsr _LVOSetDrMd(a6) ; spaces are truly made blue
lea Space.Text(pc),a0 ; The spaces
move.l YAMFG.RastPort(pc),a1
moveq #2,d0 ; there are two of them
jsr _LVOText(a6)
movem.l (sp)+,d0-d1/a0-a1/a6
rts ; That's it
; This routine is used to erase the status line. It is called by DisplayStatus
EraseStatus
movem.l d0-d3/a0-a1/a6,-(sp)
move.l YAMFG.RastPort(pc),a1
moveq #RP_JAM2,d0
move.l Graphics.Base(pc),a6
jsr _LVOSetDrMd(a6) ; Drawmode to RP_JAM2
move.l YAMFG.RastPort(pc),a1
moveq #0,d0 ; A pen to color 0
jsr _LVOSetAPen(a6)
move.l YAMFG.RastPort(pc),a1
move.l #STATUSX,d0 ; coordinates for the rectangle that will
move.l #STATUSY-6,d1 ; be drawn over the status line
move.l #STATUSX+40*8,d2
move.l #STATUSY+2,d3
jsr _LVORectFill(a6) ; draw the rectangle
movem.l (sp)+,d0-d3/a0-a1/a6
rts
; This routine displays a message in the status line,which is first cleared.
; On calling,A0 must be loaded with a pointer to the message to be displayed.
DisplayStatus: ;DisplayStatus(Message)(A0)
movem.l d0-d1/a0-a2/a6,-(sp)
bsr EraseStatus ; First erase the status line
move.l a0,a2 ; Save the message pointer (A2 is guaranteed to
move.l YAMFG.RastPort(pc),a1 ; be preserved by library routines)
moveq #RP_JAM1,d0
move.l Graphics.Base(pc),a6
jsr _LVOSetDrMd(a6) ; drawmode to RP_JAM1: only the A pen is used
move.l YAMFG.RastPort(pc),a1
moveq #1,d0
jsr _LVOSetAPen(a6) ; A Pen to color 1 (normally black or white)
move.l YAMFG.RastPort(pc),a1
move.l #STATUSX,d0 ; Coordinates of the status line
move.l #STATUSY,d1
jsr _LVOMove(a6) ; move the graphic cursor there
move.l a2,a0
.LenLoop ; count the length of the message
tst.b (a2)+ ; this is required for the Text() function
bne .LenLoop
sub.l a0,a2
subq.l #1,a2
move.l a2,d0
move.l YAMFG.RastPort(pc),a1
jsr _LVOText(a6) ; print the text
movem.l (sp)+,d0-d1/a0-a2/a6
rts
; This routine reveals where the mines were placed,it is called when the
; game has ended (the player has won or lost)
RevealMines
movem.l d0-d3/a0-a2/a6,-(sp)
lea Mines.Array(pc),a2 ; The mines grid
moveq #-1,d2 ; The current position in the array
move.l Intuition.Base(pc),a6
move.l Width(pc),d3
mulu Height+2(pc),d3 ; d3 is the size of the array
RevealLoop
addq.l #1,d2 ; increment position
cmp.l d3,d2 ; have we reached the end of the array ?
beq.s EndOfReveal ; yes...then go.
tst.b (a2)+ ; is there a mine here ?
beq.s RevealLoop ; No, check next position
move.l d2,d0 ; yes! Its position is in D0
divu Width+2(pc),d0 ; this is to split X and Y positions
moveq #0,d1 ; X position (the modulo of the division) is in D0
move.w d0,d1 ; and the Y is in D1 (the quotient of the division)
clr.w d0
swap d0
move.l YAMFG.RastPort(pc),a0
lea Mine.Image,a1 ; Image structure for a mine
lsl.l #4,d0 ; Turn X and Y positions in the grid into true
lsl.l #3,d1 ; graphic places
add.l PlayX(pc),d0
add.l PlayY(pc),d1
jsr _LVODrawImage(a6) ; Draw a mine
bra RevealLoop ; check some more positions
EndOfReveal
movem.l (sp)+,d0-d3/a0-a2/a6 ; all mines were displayed,our job
rts ; is finished
; This routine is called when the corresponding menu is selected
QuitYAMFG
addq.l #4,sp ; There is no return for this routine
bra ClearMenus ; We quit!
; This is called when the player has chosen 'About' in the menues
ShowAbout
movem.l d0-d1/a0-a4/a6,-(sp)
lea About.Body(pc),a1 ; Main message
lea About.Gad(pc),a2 ; Text for the gadget
suba.l a3,a3 ; No ReqInfo structure
move.l a3,a4 ; And no formatting things
lea About.TagList(pc),a0 ; specific TagList
move.l ReqTools.Base(pc),a6 ; Let the great reqtools.library
jsr _LVOrtEZRequestA(a6) ; do it..
movem.l (sp)+,d0-d1/a0-a4/a6
rts
; This is when the user wants to change the number of mines (with the menu)
ModifyMines
lea Mines(pc),a1 ; Variable containing the number of mines
lea HowManyMines.Title(pc),a2 ; Title for the requester
suba.l a3,a3 ; No ReqInfo structure
lea Mines.TagList(pc),a0 ; but some tags...
move.l ReqTools.Base(pc),a6 ; Request the number of mines
jsr _LVOrtGetLongA(a6)
tst.l d0 ; has the user entered a valid number ?
bne.s NewMines ; yes, go for a new game
rts ; no,the requester was canceled
; This user wants to change the width of the playfield
ChangeWidth
lea Width(pc),a1 ; Variable for the width
lea Width.Title(pc),a2 ; Title of the requester
sub.l a3,a3 ; No ReqInfo structure
lea Width.TagList(pc),a0 ; some tags...
move.l ReqTools.Base(pc),a6
jsr _LVOrtGetLongA(a6) ; Get new width
tst.l d0
bne.s NewWidth ; New game if it is valid
rts ; return if the requester was canceled
NewMines ; this is a branch for the routines that require a new
NewWidth ; game to be started
NewHeight
addq.l #4,sp ; cancel the return address on the stack
bra NewGame ; and branch to the main program
; This is exactly the same routine as ChangeWidth(),I don't think comments
; are needed.
ChangeHeight
lea Height(pc),a1
lea Height.Title(pc),a2
sub.l a3,a3
lea Height.TagList(pc),a0
move.l ReqTools.Base(pc),a6
jsr _LVOrtGetLongA(a6)
tst.l d0
bne.s NewHeight
rts
; This part contains some data for windows,menus,messages,and miscellane-
; ous little things.
YAMFG.NewWindow ; this is the NewWindow structure
dc.w 120,0 ; XY origin
dc.w 400,200 ; Width and Height in pixels
dc.b 0,1 ; FrontPen and BackPen colors
dc.l IDCMP_CLOSEWINDOW!IDCMP_RAWKEY!IDCMP_MENUPICK
; The above line contains IDCMP flags, a message will be sent by intuition
; to our program when such events occur.
dc.l WINDOWDRAG!WINDOWDEPTH!WINDOWCLOSE!ACTIVATE!NOCAREREFRESH
; This are standard window flags. There is no special strange flag,they
; are self-explanatory,thus there is no need for further explanations,you
; should understand these by yourself, so there is no need for any further
; comments, so why should I bore you to death with this ?
dc.l 0 ; No gadgets on that window
dc.l 0 ; No custom CheckMark (we don't even use a checkmark)
dc.l YAMFG.WindowName ; Name for our window
dc.l 0 ; Screen: we will just use the Workbench screen
dc.l 0 ; Bitmap: No bitmap.
dc.w 400,200 ; Minimum dimensions (useless in our case)
dc.w 400,200 ; Maximum dimensions (idem)
dc.w WBENCHSCREEN ; yes,the Workbench screen
YAMFG.Border ; Border structures for the rectangle around the play area
dc.w -1,-1 ; XY origin
dc.b 1,0,RP_JAM1,3 ; FontPen,BackPen,DrawMode,Number of vectors
dc.l YAMFG.Vectorsa,YAMFG.Borderb ; Vectors,Next border struct
YAMFG.Borderb
dc.w -1,-1 ; we use two linked border structures in
dc.b 2,0,RP_JAM1,3 ; order to create a simi-3D effect (one side
dc.l YAMFG.Vectorsb,0 ; is drawn in white,the other black)
YAMFG.Vectorsa ; This are the XY coordinates for the vectors of the firs
dc.w 0 ; border. Some fields will be altered by the program
Border.Bot1
dc.w DEFAULT_HEIGHT*8+1
dc.w 0,0
Border.Right1
dc.w DEFAULT_WIDTH*16+1,0
YAMFG.Vectorsb ; The same for the second border
Border.Right2
dc.w DEFAULT_WIDTH*16+1,1
Border.Right3
dc.w DEFAULT_WIDTH*16+1
Border.Bot2
dc.w DEFAULT_HEIGHT*8+1
dc.w 1
Border.Bot3
dc.w DEFAULT_HEIGHT*8+1
Project.Menu ; This is the menu structure for the project menu
dc.l Options.Menu ; Next menu: the 'Options' menu
dc.w 0,0 ; LeftEdge and TopEdge
dc.w 63,0 ; Width and Height (Height is unused)
dc.w MENUENABLED ; Flags: the menu is enabled
dc.l Project.Name ; guess what this is
dc.l About.MenuItem ; First item for that menu
dc.w 0,0,0,0 ; mysterious Intuition variables
About.MenuItem ; MenuItem structure for the 'About' Item
dc.l Quit.MenuItem ; Next Item
dc.w 0,0 ; LeftEdge,TopEdge
dc.w 104,8 ; Width,Height
dc.w ITEMTEXT!COMMSEQ!ITEMENABLED!HIGHCOMP ; menu flags:
; ITEMTEXT means that an IntuiText structure will be used (it could have been
; an Image),COMMSEQ means there will be a keyboard shortcut,ITEMENABLED means
; that the item can actually be selected,HIGHCOMP tells Intuition to inverse
; the colors of the menu when the mouse pointer is on it
dc.l 0 ; No Mutual-Exclude
dc.l About.IText ; Render: an IntuiText structure
dc.l 0 ; No render for selected state
dc.b 'A' ; Keyboard shortcut
dc.b 0 ; This is just a fill byte to make the address even
dc.l 0 ; No SubItem list
dc.w MENUNULL ; will be filled by Intuition for extended
; selection
dc.l ShowAbout ; This is a custom field,used by the prog to
; determine which routine is to be executed when the menu is selected
About.IText ; This is an IntuiText structure for rendering the MenuItem
dc.b 3,1,RP_COMPLEMENT,0 ; DetailPen,BlockPen,DrawMode,FillByte
dc.w 0,0 ; LeftEdge,TopEdge
dc.l 0 ; No custom font
dc.l About.MSG ; Message
dc.l 0 ; No more IntuiText structure
; The other Menu and MenuItem structures are made the same way,it would be a
; waste of time to describe them all.
Quit.MenuItem
dc.l 0
dc.w 0,8
dc.w 104,8
dc.w ITEMTEXT!COMMSEQ!ITEMENABLED!HIGHCOMP
dc.l 0
dc.l Quit.IText
dc.l 0
dc.b 'Q'
dc.b 0
dc.l 0
dc.w MENUNULL
dc.l QuitYAMFG
Quit.IText
dc.b 3,1,RP_COMPLEMENT,0
dc.w 0,0
dc.l 0
dc.l Quit.MSG
dc.l 0
Options.Menu
dc.l 0
dc.w 70,0
dc.w 63,0
dc.w MENUENABLED
dc.l Options.Name
dc.l Mines.MenuItem
dc.w 0,0,0,0
Mines.MenuItem
dc.l Width.MenuItem
dc.w 0,0
dc.w 184,8
dc.w ITEMTEXT!COMMSEQ!ITEMENABLED!HIGHCOMP
dc.l 0
dc.l Mines.IText
dc.l 0
dc.b 'M'
dc.b 0
dc.l 0
dc.w MENUNULL
dc.l ModifyMines
Mines.IText
dc.b 3,1,RP_COMPLEMENT,0
dc.w 0,0
dc.l 0
dc.l Mines.MSG
dc.l 0
Width.MenuItem
dc.l Height.MenuItem
dc.w 0,8
dc.w 184,8
dc.w ITEMTEXT!COMMSEQ!ITEMENABLED!HIGHCOMP
dc.l 0
dc.l Width.IText
dc.l 0
dc.b 'W'
dc.b 0
dc.l 0
dc.w MENUNULL
dc.l ChangeWidth
Width.IText
dc.b 3,1,RP_COMPLEMENT,0
dc.w 0,0
dc.l 0
dc.l Width.MSG
dc.l 0
Height.MenuItem
dc.l 0
dc.w 0,16
dc.w 184,8
dc.w ITEMTEXT!COMMSEQ!ITEMENABLED!HIGHCOMP
dc.l 0
dc.l Height.IText
dc.l 0
dc.b 'H'
dc.b 0
dc.l 0
dc.w MENUNULL
dc.l ChangeHeight
Height.IText
dc.b 3,1,RP_COMPLEMENT,0
dc.w 0,0
dc.l 0
dc.l Height.MSG
dc.l 0
About.TagList ; The tags for the about requester
dc.l RT_IDCMPFlags,IDCMP_MOUSEBUTTONS!INACTIVEWINDOW
; Some more IDCMP flags to react on
dc.l RTEZ_Flags,EZREQF_CENTERTEXT ; Center Text in window
dc.l TAG_END
Mines.TagList ;Tags for the number of mines requester
dc.l RTGL_Min,1 ; Minimum 1
dc.l RTGL_Max,100 ; Maximum 100
dc.l TAG_END
Width.TagList ; For the width requester
dc.l RTGL_Min,4 ; Minimum 4
dc.l RTGL_Max,MAX_WIDTH ; Maximum
dc.l TAG_END
Height.TagList ; For the height requester
dc.l RTGL_Min,4 ; Minimum
dc.l RTGL_Max,MAX_HEIGHT ; Maximum
dc.l TAG_END
Project.Name ; No need for comments
dc.b 'Project',0
About.MSG
dc.b 'About...',0
Quit.MSG
dc.b 'Quit',0
Options.Name
dc.b 'Options',0
Mines.MSG
dc.b 'Number of mines...',0
Width.MSG
dc.b 'Width...',0
Height.MSG
dc.b 'Height...',0
YAMFG.WindowName
dc.b 'YAMFG 1.0 © 1993 F.Delacroix -FreeWare',0
ReqTools.Name
dc.b 'reqtools.library',0 ; Name of the reqtools.library
Space.Text
dc.b ' ' ; Used to erase the tank image
Lost.MSG
dc.b 'You blew up ! Press a key...',0
MinesNumber.MSG
dc.b 'Number of mines around you:'
Mines.Number
dc.b '0',0
Won.MSG dc.b 'Congratulations! You''ve reached the goal!',0
About.Body ; The about message,please dont change this.
dc.b 'YAMFG 1.0 by F.Delacroix - FreeWare',10,10
dc.b 'This program may not be used for any profit',10
dc.b 'To contact me,write to:',10
dc.b 'Frédéric DELACROIX',10
dc.b '5 rue d''Artres',10
dc.b '59269 QUERENAING, FRANCE',0
About.Gad
dc.b 'Ah-ha.',0
HowManyMines.Title
dc.b 'How many mines ?',0
Width.Title
dc.b 'New width ?',0
Height.Title
dc.b 'New height ?',0
WBStarter dc.l 0 ; WBStartup received (0 if from CLI)
Graphics.Base dc.l 0 ; Base of the graphics.library
Intuition.Base dc.l 0 ; Base of intuition.library
ReqTools.Base dc.l 0 ; Base of the great reqtools.library
YAMFG.Window dc.l 0 ; Window structure (not NewWindow)
YAMFG.RastPort dc.l 0 ; RastPort for our window
YAMFG.UserPort dc.l 0 ; UserPort for it
Mines dc.l DEFAULT_MINES ; Number of mines
MinerX dc.w 0 ; X position of the tank (from 0 to width-1)
MinerY dc.w 0 ; Y position of the tank (from 0 to height-1)
Width dc.l DEFAULT_WIDTH ; Width (in columns)
Height dc.l DEFAULT_HEIGHT ; Height (in lines)
PlayX dc.l 0 ; Graphic offset for the playfield
PlayY dc.l 0
Mines.Array dcb.b MAX_WIDTH*MAX_HEIGHT,0 ; Array containing the posi-
; tions of the mines. Not that it may be that only a part of it is used as
; Width and Height may not be equal to MAX_WIDTH and MAX_HEIGHT
FinishFlag dc.b 0 ; Flag set when the game is over
section Images,DATA_C
; These are some structures that need to be in CHIP-ram:
Tank.Image ; Image structure for the tank
dc.w 0,0 ; LeftEdge,TopEdge
dc.w 16,8 ; Width,Height
dc.w 2 ; Depth: 4 colours
dc.l Tank.ImageData ; Data for the picture
dc.b $0003,$0000 ; Patterns used for rendering in bitplanes
dc.l 0 ; Next Image structure:none
Tank.ImageData
dc.w $0000,$001F,$0000,$7FFE,$FFFF,$FFFF,$FFFF,$7FFE
; Data for the first bitplane
dc.w $07C0,$0FE0,$0FE0,$7FFE,$FFFF,$8001,$7FFE,$0000
; Data for the second bitplane
Mine.Image ; Image structure for a mine
dc.w 0,0
dc.w 16,8
dc.w 2
dc.l Mine.ImageData
dc.b $0001,$0000
dc.l 0
Mine.ImageData
dc.w $0000,$0000,$0000,$0000,$0FF0,$7FFE,$7FFE,$0000
; Only one bitplane here
Target.Image ; Image structure for the target
dc.w 0,0
dc.w 16,8
dc.w 2
dc.l Target.ImageData
dc.b $0003,$0000
dc.l 0
Target.ImageData
dc.w $07E0,$0FF0,$1FF8,$3E7C,$3E7C,$1FF8,$0FF0,$07E0
dc.w $07E0,$0C30,$1818,$318C,$318C,$1818,$0C30,$07E0